MODULE BitWise;

FROM SYSTEM   IMPORT WORD,
                     ADDRESS;

FROM InOut    IMPORT Read,
                     Write,
                     WriteCard,
                     WriteHex,
                     WriteString,
                     WriteLn;

PROCEDURE ShowBits(Data : ADDRESS);

VAR Bit:        INTEGER;
    BsData:     BITSET;

BEGIN

  BsData := BITSET(Data);

  WriteHex(Data,4); Write(' ');

  FOR Bit := 15 TO 0 BY -1 DO  (* Please Note if Bit is CARDINAL *)
      IF Bit IN BsData         (* Then the for loop is ignored   *)
        THEN Write('1');
        ELSE Write('0');
      END;
  END;

  WriteLn;

END ShowBits;

PROCEDURE BitShr(Data    : ADDRESS;
                 NumBits : ADDRESS) : ADDRESS;

VAR I:           CARDINAL;
    Shift:       CARDINAL;

BEGIN

  IF CARDINAL(NumBits) < 1
    THEN RETURN Data;
  END;

  IF CARDINAL(NumBits) > 15
    THEN RETURN ADDRESS(0);
  END;

  Shift := 1;

  FOR I := 1 TO CARDINAL(NumBits) DO
      Shift := Shift * 2;
  END;

  RETURN ADDRESS(CARDINAL(Data) DIV CARDINAL(Shift));

END BitShr;

PROCEDURE BitShl(Data    : ADDRESS;
                 NumBits : ADDRESS) : ADDRESS;

VAR I:           CARDINAL;
    Shift:       CARDINAL;

BEGIN

  IF CARDINAL(NumBits) < 1
    THEN RETURN Data;
  END;

  IF CARDINAL(NumBits) > 15
    THEN RETURN ADDRESS(0);
  END;

  Shift := 1;

  FOR I := 1 TO CARDINAL(NumBits) DO
      Shift := Shift * 2;
  END;

  RETURN ADDRESS(CARDINAL(Data) * CARDINAL(Shift));

END BitShl;

VAR
  Adata,
  Bdata,
  Cdata:        WORD;
  Count:        CARDINAL;
  CReply:       CHAR;

BEGIN

  WriteLn;

  ShowBits(ADDRESS(1));
  HALT;

  FOR Count := 0 TO 16 DO
    ShowBits(BitShr(8000H,ADDRESS(Count)));
  END;

  WriteString('Done with BitShr');WriteLn;

  FOR Count := 0 TO 16 DO
    ShowBits(BitShl(ADDRESS(1),ADDRESS(Count)));
  END;

  WriteString('Done');Read(CReply);

END BitWise.
